package yxk.report.esc.hssc;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.entity.ILocaleString;
import kd.bos.dataentity.entity.LocaleString;
import kd.bos.dataentity.metadata.IDataEntityProperty;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.BasedataEntityType;
import kd.bos.entity.datamodel.events.ChangeData;
import kd.bos.entity.datamodel.events.IDataModelChangeListener;
import kd.bos.entity.datamodel.events.PropertyChangedArgs;
import kd.bos.entity.property.BasedataProp;
import kd.bos.entity.property.MulBasedataProp;
import kd.bos.form.container.Tab;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.events.CellClickEvent;
import kd.bos.form.control.events.CellClickListener;
import kd.bos.form.control.events.TabSelectEvent;
import kd.bos.form.control.events.TabSelectListener;
import kd.bos.form.field.BasedataEdit;
import kd.bos.form.field.events.AfterBindingDataEvent;
import kd.bos.form.field.events.BasedataEditListener;
import kd.bos.form.mcontrol.mobtable.*;
import kd.bos.form.mcontrol.mobtable.events.*;
import kd.bos.form.mcontrol.mobtable.tablecolumn.MobTableColumn;
import kd.bos.form.plugin.AbstractMobFormPlugin;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.metadata.entity.commonfield.TextField;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.user.UserServiceHelper;
import yxk.task.BusitripselfbillTask;
import yxk.utils.DateUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * 人员薪资报表
 */
public class UserInformatioReport extends AbstractMobFormPlugin implements IBeforeCreateMobTableColumnsListener, TabSelectListener, IDataModelChangeListener,BasedataEditListener {
    private static final Log LOG = LogFactory.getLog(UserInformatioReport.class);
    @Override
    public void registerListener(EventObject e) {
        MobTable entryGrid= this.getView().getControl("nwg5_mobtableap");
        entryGrid.addClickListener(this);
        Tab tabpageap = this.getControl("nwg5_tabap");
        tabpageap.addTabSelectListener(this);
        BasedataEdit personid = this.getControl("person");
        personid.addBasedataEditListener(this);

    }

    @Override
    public void beforeBindData(EventObject e) {
        Date years = (Date) this.getModel().getValue("nwg5_years");
        if(years != null) {
            Map<String, Map<String, Map<String, String>>> map = calculateSalarySum(years, years, null, "1");
            addText("nwg5_mobtableap", map, "1");
        }

    }

    @Override
    public void propertyChanged(PropertyChangedArgs e) {
        String name = e.getProperty().getName();
        ChangeData[] changeSet = e.getChangeSet();
        ChangeData changeData = changeSet[0];

        if("nwg5_years".equals(name)){
            Date year = (Date) changeData.getNewValue();
            Date ofYear = DateUtil.getEndTimeOfYear(year);
            Map<String,Map<String,Map<String,String>>> map = calculateSalarySum(year, ofYear,null, "1");
            addText("nwg5_mobtableap",map,"1");
            this.getView().updateView("nwg5_mobtableap");
        }else
        if("bigdate".equals(name)){
            Date enddate = (Date)this.getModel().getValue("enddate");
            Date bigdate = (Date) changeData.getNewValue();
            Date endTimeOfMonth = DateUtil.getEndTimeOfMonth(enddate);
            Map<String,Map<String,Map<String,String>>> map = calculateSalarySum(bigdate, endTimeOfMonth,null, "0");
            addText("tabpageap",map,"0");
            this.getView().updateView("nwg5_mobtableap");
        }else if("person".equals(name) || "years".equals(name)){
            Date years = (Date) this.getModel().getValue("years");
            DynamicObjectCollection person = (DynamicObjectCollection) this.getModel().getValue("person");
            Map<String,Map<String,Map<String,String>>> map = calculateSalarySum(years, years,person, "0");
            addText("nwg5_mobtableap1",map,"0");
            this.getView().updateView("nwg5_mobtableap1");
        }
    }

    public void addText(String key,Map map,String bleap) {
        MobTable mobTable = getControl(key);
        mobTable.addBeforeCreateMobTableColumnsListener(this);
        mobTable.addMobTablePackageDataHandlerListener(new UserInformatMobTableAdd(map,bleap));
    }

    /**
     *增加移动表格列
     * @param event
     */
    @Override
    public void beforeCreateMobTableColumns(BeforeCreateMobTableColumnsEvent event) {
        String key = event.getControl().getKey();
       /* if("nwg5_mobtableap1".equals(key)) {
            List<MobTableColumn> mobTableColumns = event.getMobTableColumns();
            List<MobTableColumn> mobTableColumns2 = new ArrayList<>();
            // 动态添加一个文本列
            TextField textField = new TextField();
            // 设置编辑器属性
            textField.setMustInput(true);

            MobTableColumn mobTableColumn1 = new MobTableColumn();
            // 列标识
            mobTableColumn1.setFieldKey("aaaa");
            // 列数据映射标识
            mobTableColumn1.setCaption(new LocaleString("文本列"));
            mobTableColumn1.setForeColor("#99d92b");
            mobTableColumn1.setCustomEditor(textField.createEditor());
            mobTableColumns2.add(mobTableColumn1);
            mobTableColumns.addAll(mobTableColumns2);
        }*/

    }

    public Map calculateSalarySum(Date start,Date end,DynamicObjectCollection person,String bles){

        QFilter qFilter=new QFilter("payrolldate", QCP.not_equals,null);
        Date timeOfYear = DateUtil.getFirstTimeOfYear(start);
        Date endTimeOfYear = DateUtil.getEndTimeOfYear(end);
        qFilter.and(new QFilter("payrolldate", QCP.large_equals,timeOfYear))
                    .and(new QFilter("payrolldate",QCP.less_equals,endTimeOfYear));
        //获取核算任务集合
        DynamicObject[] caltaBles = BusinessDataServiceHelper.load("hsas_calpayrolltask",
                "period,payrollscene,payrolldate,payrollgroup,calrulev,calrulev.totalsalary.number,calrulev.netsalary.number",
                qFilter.toArray());
        Map<String,Map<String,String>> conutMap=new HashMap<>();
        List<Long> caltablesIDs =new ArrayList<>();
        for (DynamicObject caltaBle : caltaBles) {
            Map<String,String> alaryMap=new HashMap<>();
            String pkValue = caltaBle.getPkValue().toString();
            alaryMap.put("totalsalary",caltaBle.getString("calrulev.totalsalary.number"));//总薪资
            alaryMap.put("netsalary",caltaBle.getString("calrulev.netsalary.number"));//净薪资
            alaryMap.put("payrolldate",caltaBle.getString("payrolldate"));
            conutMap.put(pkValue,alaryMap);
            caltablesIDs.add(Long.parseLong(pkValue));
        }
        List<String> empnumberList = new ArrayList<>();
        if(bles.equals("0")) {
            if (person != null && person.size() > 0) {
                for (DynamicObject per : person) {
                    DynamicObject fbasedataid = per.getDynamicObject("fbasedataid");
                    empnumberList.add(fbasedataid.getString("person.number"));
                }
            } else {
                DynamicObjectCollection collection = userDirectReports();
                LOG.info("UserInformatioReport.calculateSalarySum.collection:{}",collection);
                if (collection == null || collection.size() == 0) {
                    return new HashMap<>();
                }
                for (DynamicObject row : collection) {
                    empnumberList.add(row.getString("person.number"));
                }
            }
            LOG.info("empnumberList:{}",empnumberList);
            if(empnumberList == null || empnumberList.size() == 0){
                return new HashMap<>();
            }
        }

        //根据核算任务获取核算名单
        QFilter calQF=new QFilter("caltask", QCP.in,caltablesIDs)
                .and(new QFilter("calstatus", QCP.equals,"10"));
        if(bles.equals("0")) {
            calQF.and(new QFilter("empnumber", QCP.in, empnumberList));
        }
        DynamicObject[] hsasCalpeople = BusinessDataServiceHelper.load("hsas_calperson",
                "empnumber,caltask,name,filenumber,salaryfilev,calresultid,salaryfilev,empposinfo,salaryfilev.empposinfo", calQF.toArray());
        List<Long> calpersonList=new ArrayList<>();
        List<Long> companyList=new ArrayList<>();//任职经历ID
        Map<String,Map<String,String>> calpersonMap=new HashMap<>();
        LOG.info("UserInformatioReport.calculateSalarySum.hsasCalpeople:{}",hsasCalpeople);

        for (DynamicObject calperson : hsasCalpeople) {
            calpersonMap.put(calperson.getPkValue().toString(),conutMap.get(calperson.getString("caltask.id")));
            calpersonList.add((Long) calperson.getPkValue());
            companyList.add(Long.parseLong(calperson.getString("salaryfilev.empposinfo.id")));
        }

        //根据核算名单找到核算列表
        QFilter caltableQF = new QFilter("calpersonid", QCP.in,calpersonList);
        //核算列表
        DynamicObject[] caltables = BusinessDataServiceHelper.load("hsas_caltable", "calpersonid,hsas_caltableentry,hsas_caltableentry.salaryitem.number,hsas_caltableentry.salaryitem,hsas_caltableentry.calamountvalue", caltableQF.toArray());
       // bigDecimalMap 总薪资（calamount） 和 净薪资（netsalaryValue） ，名单ID为bigDecimalMap的主键
        Map<String,Map<String,String>> bigDecimalMap=new HashMap<>();
        for (DynamicObject caltable : caltables) {
            Map<String, String> calpersonidMap = calpersonMap.get(caltable.getString("calpersonid"));
            String payrolldate = calpersonidMap.get("payrolldate");//年月
            String totalsalary = calpersonidMap.get("totalsalary");//总薪资标识
            String netsalary = calpersonidMap.get("netsalary");//净薪资标识
            BigDecimal calamount = BigDecimal.ZERO;//总薪资
            BigDecimal netsalaryValue =  BigDecimal.ZERO;//净薪资
            String calpersonid = caltable.getString("calpersonid");
            //根据薪酬项目统计核算金额
            DynamicObjectCollection caltableEntry = caltable.getDynamicObjectCollection("hsas_caltableentry");
            Map<String,String> calamountMap=new HashMap<>();
            for (DynamicObject row : caltableEntry) {
                String salary = row.getString("salaryitem.number");
                BigDecimal calamountValue = row.getBigDecimal("calamountvalue");
                if(salary.equals(totalsalary)){
                    calamount = calamount.add(calamountValue).setScale(2,RoundingMode.HALF_UP);
                }else if(salary.equals(netsalary)){
                    netsalaryValue = netsalaryValue.add(calamountValue).setScale(2,RoundingMode.HALF_UP);
                }
            }
            calamountMap.put("calamount",calamount.toString());
            calamountMap.put("netsalary",netsalaryValue.toString());
            calamountMap.put("payrolldate",payrolldate);
            bigDecimalMap.put(calpersonid,calamountMap);
        }
        if(bles.equals("1")){
           return orgMonthCalculateSalarySum(hsasCalpeople,companyList,bigDecimalMap);
        }
        if(bles.equals("0")){
            return personMonthCalculateSalarySum(hsasCalpeople,bigDecimalMap);
        }

        Map<String,Map<String,Map<String,String>>> map=new HashMap<>();

        return map;
    }


    /**
     * 根据组织分类获取每月的总集合
     * @param hsasCalpeople  核算名单集合
     * @param companyList   人员任职经历ID集合
     * @param bigDecimalMap 核算金额集合
     * @return
     */
    private  Map<String,Map<String,Map<String,String>>> orgMonthCalculateSalarySum(DynamicObject[] hsasCalpeople,List<Long> companyList, Map<String,Map<String,String>> bigDecimalMap){
        Map<String,Map<String,Map<String,String>>> map=new HashMap<>();

        //收集所有人员的所属公司
        DynamicObject[] empposorgrelhr = BusinessDataServiceHelper.load("hsas_empposorgrelhr", "company",
                new QFilter("id", QCP.in, companyList).toArray());
        Map<String,Map<String,String>> empMap=new HashMap<>();
        for (DynamicObject emp : empposorgrelhr) {
            Map<String,String> panyMap=new HashMap<>();
            DynamicObject company = emp.getDynamicObject("company");

            panyMap.put("companyId",company.getPkValue().toString());
            panyMap.put("companyNumber",company.getString("number"));
            panyMap.put("companyName",company.getString("name"));
            empMap.put(emp.getPkValue().toString(),panyMap);
        }

        for (DynamicObject calperson : hsasCalpeople) {
            //获取当前人员的公司信息
            String company = calperson.getString("salaryfilev.empposinfo.id");
            Map<String, String> companyMap = empMap.get(company);
            if(companyMap==null){
                continue;
            }
            //公司编码
            String companyNumber = companyMap.get("companyNumber");
            //获取人员（总薪资、净薪资和薪资年月）
            Map<String, String> calpersonBigMap = bigDecimalMap.get(calperson.getPkValue().toString());
            String payrolldate = calpersonBigMap.get("payrolldate");//年月
            String calamount = calpersonBigMap.get("calamount");//总薪资
            String netsalary = calpersonBigMap.get("netsalary");//净薪资
            //获取所属公司下面的月份数据
            Map<String, Map<String, String>> monthMap = map.get(companyNumber);
            //公司下面薪资Map
            Map<String, String> bigMap=new HashMap<>();
            if(monthMap == null){
                monthMap = new HashMap<>();
                bigMap.put("calamount",calamount);
                bigMap.put("netsalary",netsalary);
                monthMap.put(payrolldate,bigMap);
            }else{
                bigMap = monthMap.get(payrolldate);
                if(bigMap != null && bigMap.size() > 0){
                    BigDecimal calamountBig=new BigDecimal(bigMap.get("calamount"));
                    calamountBig = calamountBig.add(new BigDecimal(calamount)).setScale(2,RoundingMode.HALF_UP);
                    BigDecimal netsalaryBig=new BigDecimal(bigMap.get("netsalary"));
                    netsalaryBig = netsalaryBig.add(new BigDecimal(netsalary)).setScale(2, RoundingMode.HALF_UP);

                    bigMap.put("calamount",calamountBig.toString());
                    bigMap.put("netsalary",netsalaryBig.toString());
                }else {
                    bigMap=new HashMap<>();
                    bigMap.put("calamount",calamount);
                    bigMap.put("netsalary",netsalary);
                }
                monthMap.put(payrolldate,bigMap);
            }
            map.put(companyNumber,monthMap);
        }
        return map;
    }

    /**
     *
     * @param hsasCalpeople  核算名单集合
     * @param bigDecimalMap  核算金额集合
     * @return
     */
    private Map<String,Map<String,Map<String,String>>> personMonthCalculateSalarySum(DynamicObject[] hsasCalpeople, Map<String,Map<String,String>> bigDecimalMap){
        Map<String,Map<String,Map<String,String>>> map=new HashMap<>();
        for (DynamicObject calperson : hsasCalpeople) {
            Map<String, String> personMap = bigDecimalMap.get(calperson.getPkValue().toString());
            String calamount = personMap.get("calamount");//净薪资
            String netsalary = personMap.get("netsalary");//总薪资
            String payrolldate = personMap.get("payrolldate");//年月
            String empnumber = calperson.getString("empnumber");

            Map<String, Map<String, String>> numberMap = map.get(empnumber);
            Map<String, String> payrollMap =null;
            if( numberMap != null && numberMap.size() > 0 ){
                payrollMap = numberMap.get(payrolldate);
                if( payrollMap != null && payrollMap.size() > 0 ){
                    String mount = payrollMap.get("mount");
                    String salary = payrollMap.get("salary");
                    //净新资
                    BigDecimal bigCalamount=new BigDecimal(mount);
                    BigDecimal decimal = bigCalamount.add(new BigDecimal(calamount));
                    payrollMap.put("mount",decimal.toString());
                    //总薪资
                    BigDecimal bigNetsalary=new BigDecimal(netsalary);
                    BigDecimal sal = bigNetsalary.add(new BigDecimal(salary));
                    payrollMap.put("salary",sal.toString());

                }else {
                    payrollMap = new HashMap<>();
                    payrollMap.put("mount",calamount);
                    payrollMap.put("salary",netsalary);
                }
            }else{
                numberMap = new HashMap<>();
                payrollMap = new HashMap<>();
                payrollMap.put("mount",calamount);
                payrollMap.put("salary",netsalary);
            }

            numberMap.put(payrolldate,payrollMap);
            map.put(empnumber,numberMap);
        }
        return map;
    }
    @Override
    public void tabSelected(TabSelectEvent tab) {
        String tabKey = tab.getTabKey();
        if("tabpageap".equals(tabKey)){
            Date bigdate = (Date)this.getModel().getValue("years");

            Map<String,Map<String,Map<String,String>>> map = calculateSalarySum(bigdate, bigdate, null,"0");
            addText("nwg5_mobtableap1",map,"0");
            this.getView().updateView("nwg5_mobtableap1");
        }
    }


    @Override
    public void afterBindingData(AfterBindingDataEvent evt) {
        BasedataEdit edit = (BasedataEdit) evt.getSource();
        Object v = evt.getDataEntity();
        Object editSearchProp;
        Object displayProp = "";
        if (v == null) {
            return;
        }
        BasedataEntityType dt;
        if (((DynamicObject) v).getDataEntityType() instanceof BasedataEntityType) {
            dt = (BasedataEntityType) ((DynamicObject) v).getDataEntityType();
        } else {
            dt = (BasedataEntityType) ((BasedataProp) edit.getProperty()).getComplexType();
        }

        //获取数据包中的名称字段值
        String nameKey = dt.getNumberProperty();
        IDataEntityProperty p2 = dt.findProperty(nameKey);
        if (p2 != null) {
            displayProp = p2.getValueFast(v);
            if (displayProp instanceof ILocaleString) {
                displayProp = displayProp.toString();
            }
        }

        //动态修改多选基础资料的显示属性为名称(部门)
        if ("person".equals(edit.getKey())) {
            nameKey = "person";
        }
        IDataEntityProperty p4 = dt.findProperty(nameKey);
        if (p4 != null) {
            DynamicObject row=(DynamicObject)p4.getValueFast(v);
            String name = row.getString("name");
            displayProp = String.format("%s",name);
        }

        editSearchProp = getEditSearchProp(edit.getProperty());
        //编辑显示属性也同步修改
        if (StringUtils.isNotBlank(editSearchProp)) {
            editSearchProp = editSearchProp.toString().replace("number", displayProp == null ? "" : displayProp.toString());
        }
        //设置显示属性
        evt.setDisplayProp(displayProp.toString());
        //设置编辑显示属性
        evt.setEditSearchProp(editSearchProp == null ? "" : editSearchProp.toString());
    }

    private String getEditSearchProp(IDataEntityProperty property) {
        BasedataProp basedataProp = null;
        if ((property instanceof BasedataProp)) {
            basedataProp = (BasedataProp) property;
        } else if (property instanceof MulBasedataProp) {
            basedataProp = (BasedataProp) ((MulBasedataProp) property).getRefBaseProp();
        }

        return basedataProp.getEditSearchProp();
    }

    /**
     * 获取人员直接下属
     * @return
     */
    private DynamicObjectCollection userDirectReports() {
        long currentUserId = UserServiceHelper.getCurrentUserId();
        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle(currentUserId, "bos_user");
        DynamicObject attendPerson = BusinessDataServiceHelper.loadSingleFromCache("hrpi_empposorgrel", "id,person,position",
                new QFilter("person.number", QCP.equals, bosUser.getString("number")).toArray());
        if (attendPerson != null) {
            //获取任职经历中的岗位，根据岗位获取下级人员
            DynamicObject position = attendPerson.getDynamicObject("position");
            DynamicObject[] positionhr = BusinessDataServiceHelper.load("hbpm_positionhr", "id,parent",
                    new QFilter("parent", QCP.equals, position.getPkValue()).and("iscurrentversion", QCP.equals, true).toArray());
            List<Long> list = new ArrayList<>();
            for (DynamicObject row : positionhr) {
                list.add(Long.parseLong(row.getPkValue().toString()));
            }
            LOG.info("UserInformatioReport.userDirectReports.list:{}",list);
            DynamicObject[] loaded = BusinessDataServiceHelper.load("hrpi_empposorgrel", "position,person",
                    new QFilter("position", QCP.in, list).and("iscurrentversion", QCP.equals, true).toArray());
            LOG.info("UserInformatioReport.userDirectReports.list:{}",loaded);
            DynamicObjectCollection collection = new DynamicObjectCollection();
            List listNumber=new ArrayList<>();
            for (int i = 0; i < loaded.length; i++) {
                collection.add(i, loaded[i]);
            }
            return collection;
        }
        return null;
    }
}
